﻿# Set up a bunch of useful aliases...

Set-Alias psconfig ((Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0').Location + "Bin\psconfig.exe")
Set-Alias stsadm ((Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0').Location + "Bin\stsadm.exe")



###########################################################################
#  
#   Insert your script below
#
###########################################################################

Write-Host -ForegroundColor Yellow "WAC: Installing and Configuring WAC for $env:farmname."

$wordSvc = Get-SPServiceApplication | where { $_.TypeName -like "*word*" }
if ($wordSvc -eq $null){
#continue
} else {
Write-Host "WAC has already been installed. skipping step."
exit 0
}
$env:serverrole="APP"

#------------------------------------------------------------------------------
# ActivateFeaturesOnAllSites 
# Activates WAC Features in Dogfood
# This function will query the entire farm, asking for the list of all sites that have 
# a particular template, and will activate WAC on them.  THis could take a while
# so it should probably be tested on a large farm before we deploy it
#------------------------------------------------------------------------------
Function ActivateFeaturesOnAllSites
{

  # First, get the feature identities, NEED TO USE THE UBER FEATURE NOT INDIVIDUAL FEATURES
  #$UberFeatureId = $(Get-SPFeature -limit all | where {$_.displayname -eq "OfficeWebApplications"}).Id
  $UberFeatureId = $(Get-SPFeature -limit all | where {$_.displayname -eq "OfficeWebApps"}).Id
  $onenoteFeature = Get-SPFeature -Identity 3d433d02-cf49-4975-81b4-aede31e16edf

  # Leave S3 things... PPT is going to fix this on their own
#  $PowerPointBroadcastId = $(GET-SPFeature -Limit All | where {$_.displayname -eq "PowerPointBroadcastServer"}).Id


  Write-Host "-----------------Getting all sites for the farm-----------------"
  $allSites = Get-spwebapplication | get-spsite -limit all 
  Write-Host "Found the following sites"
  Write-Host $allSites


  # Finally, enable the features on each of these sites.
  # Todo : I'm sure that there's a way to make a list out of the SPWebs, and iterate through them, however, I don't have the time to figure that out.

  Write-Host "----------------Activating feature for each site----------------"
  Write-Warning "IF YOU HAVE RAN THIS SCRIPT ON ANOTHER FRONT-END IN THE FARM"
  Write-Warning "ALREADY YOU ARE ABOUT TO SEE A LOT OF RED TEXT BELOW. THATS OK :)"
  Write-Warning "It will say something like ... is already activated at scope ... "

  if ($allSites)
  {
  	foreach ($i in $allSites) 
	{ 
		Write-Host "----------------Currently activating features on site " + $i  
		Enable-SPFeature -Identity $UberFeatureId -Url $i.Url -force
		Disable-SPFeature -Identity $onenoteFeature -Url http://localhost -Confirm:$false
		Enable-SPFeature -Identity $onenoteFeature -Url http://localhost -Confirm:$false
#		Enable-SPFeature -Identity $PowerPointBroadcastId -Url $i.Url
	}
  }

  Write-Host "----------------Activating feature for each site----------------"
  Write-Warning "IF YOU HAVE RAN THIS SCRIPT ON ANOTHER FRONT-END IN THE FARM"
  Write-Warning "ALREADY YOU WILL SEE A LOT OF RED TEXT ABOVE. THATS OK :)"
  Write-Warning "It will say something like ... is already activated at scope ... "
}

#------------------------------------------------------------------------------
# CreateSPWordViewingServiceApplication
# This workaround creates a Service Application using WACs existing cmdlets
#------------------------------------------------------------------------------
Function CreateSPWordViewingServiceApplication
{
  Write-Host "-----------------Creating Office Viewing Service Application-----------------" 
  
  Write-Host "Starting Word Viewing Service"
 
  
foreach ($server in $env:WACServers){

 $ConversionService = Get-SPServiceInstance | where {$_.TypeName -match "Word Viewing Service" -and $_.Server -like "*$server*"} 
   $ConversionServiceId = $ConversionService.Id

  # If service is already started this will do nothing so no need to check
  Start-SPServiceInstance -Identity $ConversionServiceID   
}

  # Reset the system to ensure that everything in word viewing service is now ready to go
  iisreset

  Write-Host "Seeing if we have already created a WordViewingServiceApplication"
  $serviceappcheck = Get-SPServiceApplication | where {$_.DisplayName -eq "WACServiceApplication"}
 
  # if our search doesnt find a word viewing service application, we should create one
  if($serviceappcheck -eq $null)
  {
    Write-Host "It looks like you don't have a Word Viewing Service Application. We should create one."	
    Write-Host "Creating New Word Viewing Service Application"	
    $bindingFlags = [System.Reflection.BindingFlags]::InvokeMethod -bor [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::NonPublic
    #$appPool = [Microsoft.SharePoint.Administration.SPServiceApplicationPool].InvokeMember("EnsureSystemDefault", $bindingFlags, $null, $null, $null)
    
	$appPool = Get-SPServiceApplicationPool | where {$_.DisplayName -eq "SharePoint Web Services System Default"}
	if( $appPool -eq $null )
	{
		echo "IIS application pool $metaServiceAppPool not found, creating one..."
		$acct =  Get-SPManagedAccount # | ? { $_.username -contains $env:apppoolacct }
		if ( $acct -eq $null )
		{
			Write-Error "Could not find managed account for farm admin."
			exit 1;
		}

		$appPool = new-SPServiceApplicationPool -account $acct -name "SharePoint Web Services System Default"
		if ( !$? )
		{
			Write-Error "Failed to create app pool $metaServiceAppPool";
			exit 1;
		}
	}
	
      New-SPWordViewingServiceApplication -Name WACServiceApplication -ApplicationPool $appPool
  }
  
  else
  {
    Write-Warning "It appears you already have a WordServiceApplication. If you have already run this script on another machine in the farm this is expected"
  }
}


#------------------------------------------------------------------------------
# CreateSPWordViewingServiceApplicationProxy, yes longest name ever
# This workaround creates a Service Application Proxy using WACs existing cmdlets
#------------------------------------------------------------------------------
Function CreateSPWordViewingServiceApplicationProxy
{
  Write-Host "-----------------Creating Word Viewing Service App Proxy-----------------"

  $ServiceAppId = $(Get-SPServiceApplication | where {$_.DisplayName -eq "WACServiceApplication"}).Id

  Write-Host "Checking to see if we have already created a Word Viewing Service App Proxy"
  $serviceappproxycheck = Get-SPServiceApplicationProxy | where {$_.DisplayName -eq "WACServiceAppProxy"}


  if($serviceappproxycheck -eq $null)
  {
    Write-Host "It looks like you don't have a word viewing service app proxy. We should create one"
    Write-Host "Creating proxy connected to Service Application created above"
    # By NOT specifying the -Default parameter, this proxy gets associated with the Default Proxy Group, which we want 
    New-SPWordViewingServiceApplicationProxy -Name WACServiceAppProxy -ServiceApplication $ServiceAppId
  }

  else
  {
    Write-Warning "It looks like you already have a WordServiceApplicationProxy. If you have already run this script on another machine in the farm this is expected"
  }
}

#------------------------------------------------------------------------------
# Get the ID of the WordViewingServiceApplication we just created
# Then change the number of active word workers to six
#------------------------------------------------------------------------------
Function ChangeActiveWordWorkersToSix
{
  Write-Host "-----------------Changing Active Word Workers to Six-----------------"

  # Get the ID of the service application we just created
  $ServiceAppId = $(Get-SPServiceApplication | where {$_.DisplayName -eq "WACServiceApplication"}).Id

  # 
  Set-SPWordViewingServiceApplication -Identity $ServiceAppId -MaxActiveProcessCount 6
  Write-Host "Changed Word workers to six"
}


#------------------------------------------------------------------------------
# CreateSPPowerPointServiceApplication
# This workaround creates a Service Application using PPT's existing cmdlets
#------------------------------------------------------------------------------
Function CreateSPPowerPointServiceApplication
{
  Write-Host "-----------------Creating PowerPoint Web Service Application-----------------" 
  
  Write-Host "Starting PowerPoint Web Service"
  
foreach ($server in $env:WACServers){

 $ConversionService = Get-SPServiceInstance | where {$_.TypeName -like "*PowerPoint*" -and $_.Server -like "*$server*"} 
   $ConversionServiceId = $ConversionService.Id

  # If service is already started this will do nothing so no need to check
  Start-SPServiceInstance -Identity $ConversionServiceID   
}


  # Reset the system to ensure that everything in PPT viewing service is now ready to go
  iisreset

  Write-Host "Seeing if we have already created a PowerPointServiceApplication"
  $serviceappcheck = Get-SPPowerPointServiceApplication
 
  # if our search doesnt find a PPT viewing service application, we should create one
  if($serviceappcheck -eq $null)
  {
    Write-Host "It looks like you don't have a PowerPoint Service Application. We should create one."	
    Write-Host "Creating New PowerPoint Service Application"	
    $appPool = Get-SPServiceApplicationPool | where {$_.DisplayName -eq "SharePoint Web Services System Default"}
	if( $appPool -eq $null )
	{
		echo "IIS application pool $metaServiceAppPool not found, creating one..."
		$acct =  Get-SPManagedAccount | ? { $_.username -contains $env:apppoolacct }
		if ( $acct -eq $null )
		{
			Write-Error "Could not find managed account for farm admin."
			exit 1;
		}

		$appPool = new-SPServiceApplicationPool -account $acct -name "SharePoint Web Services System Default"
		if ( !$? )
		{
			Write-Error "Failed to create app pool $metaServiceAppPool";
			exit 1;
		}
	}
    New-SPPowerPointServiceApplication -Name PPTServiceApplication -ApplicationPool $appPool
  }
  else
  {
    Write-Warning "It appears you already have a PPTServiceApplication. If you have already run this script on another machine in the farm this is expected"
    Write-Warning "You no longer have to run this scipt on each backend so you shouldn't see this message. Assert 'fail'."
  }
}

#------------------------------------------------------------------------------
# CreateSPPowerPointServiceApplicationProxy
# This workaround creates a Service Application Proxy using PPT's existing cmdlets
#------------------------------------------------------------------------------
Function CreateSPPowerPointServiceApplicationProxy
{
  Write-Host "-----------------Creating PowerPoint Service Application Proxy-----------------"

  $ServiceAppId = $(Get-SPPowerPointServiceApplication | where {$_.DisplayName -eq "PPTServiceApplication"}).Id

  Write-Host "Checking to see if we have already created a PPT Service App Proxy"
  $serviceappproxycheck = Get-SPPowerPointServiceApplicationProxy | where {$_.DisplayName -eq "PPTServiceAppProxy"}


  if($serviceappproxycheck -eq $null)
  {
    Write-Host "It looks like you don't have a PPT  service app proxy. We should create one"
    Write-Host "Creating proxy connected to Service Application created above"
    New-SPPowerPointServiceApplicationProxy -Name PPTServiceAppProxy -ServiceApplication $ServiceAppId -AddToDefaultGroup
  }
  else
  {
    Write-Warning "It looks like you already have a PPTServiceApplicationProxy. If you have already run this script on another machine in the farm this is expected"
    Write-Warning "You no longer have to run this script on each backend so you shouldn't see this message. Assert 'fail'."
  }
}


#------------------------------------------------------------------------------
# There's a Livebooks xml file called serverfileslivebooks.xml that needs to be 
# deleted b/c WAC doesnt work with onenote. deleting this file prevents the default
# click scenario, therefore stopping people from trying this
#------------------------------------------------------------------------------
Function DeleteLivebooksXML
{
  Write-Host "-----------------Deleting Livebooks XML File-----------------"

  # This is the path to where the file lives, yes it is hardcoded to ship only, we dont care about debug, mirror runs ship only
  $LivebooksXMLPath = $env:programfiles + "\Common Files\Microsoft Shared\Web Server Extensions\14\Template\XML\serverfileslivebooks.xml"

  # if we find the file, delete it, if we dont find the file, cry, -force in case the computer tries to stop us
  if(test-path $LivebooksXMLPath)
  {
    Remove-Item -Path $LivebooksXMLPath -force
  }
  else
  {
    Write-Host "Did not find file serverfileslivebooks.xml" -foregroundcolor "red" -backgroundcolor "black"
    Write-Host "Therefore this file was not deleted. WAC may still be activated for OneNote" -foregroundcolor "red" -backgroundcolor "black"
  }
}

#------------------------------------------------------------------------------
# Per bug O14:293174 the reg key secMinTimeSinceLastHotWriteThreshold needs to 
# have a default value of 3600 in order to work around a known issue. This reg key
# currently doesnt exist so it needs to be created as well. Kiranav or Delackme
# are both good contacts if you do not understand why this is needed.
#------------------------------------------------------------------------------
Function AddCoalesceRegKey
{
  Write-Host "-----------------Add Coalesce RegKey O14:293174-----------------"

  # first we must create the location where the registry key will live since it doesnt exist by default
  new-item -path "hklm:\software\microsoft\office\14.0\Common\Internet"

  # now that its location exists, we can create the reg key itself, giving it the correct value of 3600
  new-itemproperty -path "hklm:\software\microsoft\office\14.0\Common\Internet" -name "secMinTimeSinceLastHotWriteThreshold" -type DWORD -value 3600
}


#------------------------------------------------------------------------------
# CreatePowerPointBroadcastSite
# Create a site collection under /sites/broadcast using the PowerPoint Broadcast
# site template, only if the site does not already exist.
#------------------------------------------------------------------------------

Function CreatePowerPointBroadcastSite
{
  Write-Host "-----------------Creating PowerPoint Broadcast Site-----------------"

  $rootSites = Get-SPWebApplication $env:farmurl | Get-SPSite -Limit ALL | where { $_.ServerRelativeUrl -eq "/" }

  foreach ($rootSite in $rootSites)
  {
    $url = $rootSite.Url + "/sites/broadcast"
    if (( Get-SPWeb $url) -ne $null)
    {
	Write-Host "Found old PowerPoint Broadcast Site. Deleting it."
	remove-spsite  $url -Confirm:$false
    }

    Write-Host "Creating new broadcast site $url."
    $broadcastTempl = Get-SPWebTemplate | where { $_.Title -eq "PowerPoint Broadcast Site" }
    New-SPSite -Url $url -OwnerAlias $env:apppoolacct -Template $broadcastTempl
    New-SPUser -web $url -UserAlias "NT AUTHORITY\Authenticated Users" -PermissionLevel "Contribute" -Group "Broadcast Attendees"
    New-SPUser -web $url -UserAlias "REDMOND\office portal - office contributors" -PermissionLevel "Contribute" -Group "Broadcast Presenters"
    New-SPUser -web $url -UserAlias REDMOND\red_officewebauthor -PermissionLevel "Contribute" -Group "Broadcast Presenters"
    New-SPUser -web $url -UserAlias "NT AUTHORITY\authenticated users" -PermissionLevel "Read"
  	New-SPUser -web $url -UserAlias "northamerica\npenner" -PermissionLevel "Full Control" -Group "Broadcast Administrators"
	New-SPUser -web $url -UserAlias "northamerica\adityak" -PermissionLevel "Full Control" -Group "Broadcast Administrators"
	New-SPUser -web $url -UserAlias "northamerica\tommysu" -PermissionLevel "Full Control" -Group "Broadcast Administrators"
	#New-SPUser -web $url -UserAlias "northamerica\Office Broadcast Dogfood Users" -Group "Broadcast Attendees"
	New-SPUser -web $url -UserAlias "northamerica\Office Broadcast Dogfood Users" -Group "Broadcast Presenters"
  }  
} 


if ($env:ServerRole -eq "wfe")
{
  $wfes = $env:wfeservers.split(";");
  
  # Run this only on the first web front end
  if( $env:COMPUTERNAME -eq $wfes[0] )
  {
  	ActivateFeaturesOnAllSites
	CreatePowerPointBroadcastSite
  }
  
  # DeleteLivebooksXML, we want onenote to be default click again
  # AddCoalesceRegKey, coalesce regkey is no longer needed, that bug has been fixed
}

if ($env:ServerRole -eq "app")
{
  CreateSPWordViewingServiceApplication
  CreateSPWordViewingServiceApplicationProxy
  ChangeActiveWordWorkersToSix
  CreateSPPowerPointServiceApplication
  CreateSPPowerPointServiceApplicationProxy
}


iisreset | Out-Null
Write-Host "-----------------WAC MOSS activation has completed!-----------------"
Write-Host -ForegroundColor Yellow "WAC: Installing and Configuring WAC for $env:farmname. COMPLETED"


###########################################################################
#  
#   End
#
###########################################################################